package com.loong.web.gp4j.encrypt.ui;

import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.WindowConstants;

import com.loong.web.gp4j.encrypt.util.Icons;
import com.loong.web.gp4j.encrypt.util.Symmetric;

/**
 * 主框架窗口
 *
 * @author 张成轩
 */
public class UI extends JFrame {

	private static final long serialVersionUID = 8801229824085520583L;

	private static final String ICON = "favicon.png";
	private static final String TITLE = "GP4j";
	private static final String KEY = "GP4J_KEY";

	private JButton encrypt;
	private JButton key;
	private JTextField content;
	private JTextArea crypto;

	/**
	 * 构造方法
	 */
	public UI() {

		initEvent();
		initStyle();
		initComp();
	}

	/**
	 * 初始化事件
	 */
	private void initEvent() {

		this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
	}

	/**
	 * 初始化样式
	 */
	private void initStyle() {

		// 设置图标
		this.setIconImage(Icons.getImage(ICON));
		// 设置窗口名称
		this.setTitle(TITLE);
		// 设置窗口大小
		this.setSize(500, 300);
		// 禁止改变大小
		this.setResizable(false);
		// 设置窗口居中
		// 获取屏幕的尺寸
		Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
		int x = screen.width / 2 - this.getWidth() / 2;
		int y = screen.height / 2 - this.getHeight() / 2;
		// 设置显示位置
		this.setLocation(x, y);
	}

	/**
	 * 初始化组件
	 */
	private void initComp() {

		// 设置布局
		this.setLayout(new GridBagLayout());

		// 布局工具
		GridBagConstraints c = new GridBagConstraints();

		c.insets = new Insets(20, 20, 0, 5);
		c.fill = GridBagConstraints.HORIZONTAL;
		c.weightx = 1;
		this.add(buildContent(), c);

		c.gridx = 1;
		c.insets = new Insets(20, 5, 0, 5);
		c.fill = GridBagConstraints.NONE;
		c.weightx = 0;
		this.add(buildEncrypt(), c);

		c.gridx = 2;
		c.insets = new Insets(20, 0, 0, 20);
		this.add(buildKey(), c);

		c.gridx = 0;
		c.gridy = 1;
		c.gridwidth = 3;
		c.insets = new Insets(20, 20, 20, 15);
		c.fill = GridBagConstraints.BOTH;
		c.weightx = 1;
		c.weighty = 1;
		this.add(buildCrypto(), c);
	}

	/**
	 * @return 文本录入框
	 */
	private JTextField buildContent() {

		content = new JTextField();
		content.setFocusable(true);
		return content;
	}

	/**
	 * @return 解密按钮
	 */
	private JButton buildEncrypt() {

		encrypt = new JButton("加密");
		encrypt.setMargin(new Insets(2, 8, 2, 8));
		encrypt.setCursor(new Cursor(Cursor.HAND_CURSOR));
		encrypt.setFocusable(false);
		encrypt.addActionListener((ActionEvent e) -> encrypt());
		return encrypt;
	}

	/**
	 * @return 随机密钥按钮
	 */
	private JButton buildKey() {

		key = new JButton("随机密钥");
		key.setMargin(new Insets(2, 8, 2, 8));
		key.setCursor(new Cursor(Cursor.HAND_CURSOR));
		key.setFocusable(false);
		key.addActionListener((ActionEvent e) -> key());
		return key;
	}

	/**
	 * @return 密文显示框
	 */
	private JScrollPane buildCrypto() {

		crypto = new JTextArea();
		crypto.setEditable(false);
		crypto.setLineWrap(true);
		return new JScrollPane(crypto);
	}

	/**
	 * 加密处理
	 */
	private void encrypt() {

		String text = content.getText();
		if (text == null || text.isEmpty()) {
			JOptionPane.showMessageDialog(this, "请输入待加密信息！", "提示", JOptionPane.INFORMATION_MESSAGE);
			return;
		}
		String key = System.getenv(KEY);
		if (key == null) {
			JOptionPane.showMessageDialog(this, "尚未设置密钥，设置方式参见 GP4j 使用说明。", "提示", JOptionPane.ERROR_MESSAGE);
			return;
		}
		try {
			crypto.setText(Symmetric.encrypt(text, key));
		} catch (Exception e) {
			JOptionPane.showMessageDialog(this, e.getMessage(), "加密失败", JOptionPane.ERROR_MESSAGE);
		}
	}

	private void key() {

		content.setText("");
		try {
			crypto.setText(Symmetric.getKey());
		} catch (Exception e) {
			JOptionPane.showMessageDialog(this, e.getMessage(), "创建密钥失败", JOptionPane.ERROR_MESSAGE);
		}
	}
}
